<?php

class Android {

	// Mischt zwei nach dem Datum sortierte Arrays ineinander, so dass
	// der Ergebnisarray wieder sortiert ist.
	static function sortedArrayMerge($a1, $a2)
	{
		$i1 = $i2 = 0;
		$res = array();
		$total_length = count($a1) + count($a2);
		for ($j=0; $j<$total_length; $j++)
		{
			if ($a1[$i1]['date'] < $a2[$i2]['date'])
			{
				$res[$j] = $a2[$i2++];
			}
			else
			{
				$res[$j] = $a1[$i1++];
			}
		}

		return $res;
	}

	/**
	 * Liefert eine Zusammenfassung der den Nutzer betreffenden Änderungen seit 
	 * einem bestimmten Zeitpunkt.
	 * @param since Zeitpunkt in Sekunden (nicht Millisekunden!) nach Neujahr 1970
	 * @return Tabellenspalten:<p/>
	 * {@code type} Resourcen-Typ<p/>
	 * {@code count} Anzahl der geänderten Resourcen von diesem Typ
	 */
	static function getNotifications($user_id, $since) 
	{

		$notifications = array();
		$feed = Android::getFeed($user_id, $since);
		foreach ($feed as $entry)
		{
			$type = $entry['object_type'];
			if ($notifications[$type]) $notifications[$type]++;
			else $notifications[$type] = 1;
		}

		$ret = array();
		foreach ($notifications as $type => $count)
		{
			$ret[] = array(
				'type'	=> $type,
				'count'	=> (string) $count
			);
		}

		return (array) $ret;
		
	}

	/**
	 * Liefert alle den Nutzer betreffenden Änderungen seit einem Bestimmten 
	 * Zeitpunkt.
	 * @param since Zeitpunkt in Sekunden (nicht Millisekunden!) nach Neujahr 1970
	 * @return Tabellenspalten:<p/>
	 * {@code object_id} ID der geänderten Resource<p/>
	 * {@code object_type} Typ der geänderten Resource<p/>
	 * {@code title} Name der Resource<p/>
	 * {@code description} Beschreibung der Änderung<p/>
	 * {@code date} Zeitpunkt der Änderung<p/>
	 * {@code read} {@code 1} wenn die Resource seit der Änderung geöffnet wurde,
	 * {@code 0} sonst
	 */
	static function getFeed($user_id, $since)
	{
		$feed = array();

		$feed = Android::sortedArrayMerge($feed, Android::getNewsFeed($user_id, $since));
		$feed = Android::sortedArrayMerge($feed, Android::getMessageFeed($user_id, $since));
		$feed = Android::sortedArrayMerge($feed, Android::getScheduleFeed($user_id, $since));

		return $feed;
	}

	static function getNewsFeed($user_id, $since)
	{

		$query = "SELECT 
			news.news_id, 
			object_user_visits.object_id, 
			news.topic, 
			seminare.Name, 
			news.chdate,
			object_user_visits.visitdate
			
			FROM news
			LEFT JOIN news_range USING (news_id)
			LEFT JOIN seminare ON (news_range.range_id = seminare.Seminar_id)
			LEFT JOIN seminar_user USING (Seminar_id)
			LEFT JOIN object_user_visits ON (news.news_id = object_user_visits.object_id AND object_user_visits.user_id = seminar_user.user_id)
			WHERE seminar_user.user_id = '$user_id'
			AND news.chdate > '$since'
			ORDER BY news.chdate DESC
			";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			if ($data['chdate'] < $data['visitdate'])
			{
				$read = '1';
			} else {
				$read = '0';
			}
			$ret[] = array(
				'object_id'   => $data['news_id'],
				'object_type' => 'news',
				'title'       => $data['topic'],
				'description' => $data['Name'],
				'date'        => $data['chdate'],
				'read'        => $read
			);
		}

		return (array) $ret;
	}

	static function getMessageFeed($user_id, $since)
	{
		$query = "SELECT message.message_id, message.subject, Vorname, Nachname, message.mkdate, message_user.readed
			FROM message
		        LEFT JOIN message_user USING (message_id)
			LEFT JOIN auth_user_md5 ON (auth_user_md5.user_id = autor_id)
			WHERE message_user.user_id='$user_id'
			AND snd_rec='rec'
			AND message.mkdate > '$since'
			ORDER BY message.mkdate DESC";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'object_id'   => $data['message_id'],
				'object_type' => 'message',
				'title'       => $data['subject'],
				'description' => $data['Vorname']." ".$data['Nachname'],
				'date'        => $data['mkdate'],
				'read'        => $data['readed']
			);
		}

		return (array) $ret;

	}

	static function getVote($seminar_id, $user_id)
	{

	}

	static function getForum($seminar_id, $user_id)
	{

	}

	static function getWiki($seminar_id, $user_id)
	{

	}

	static function getScheduleFeed($user_id, $since)
	{
		$query = "SELECT 
			termine.termin_id, 
			themen.title, 
			seminare.Name, 
			termine.date, 
			termine.end_time, 
			termine.chdate AS termine_chdate,
			themen.chdate AS themen_chdate, 
			object_user_visits.visitdate
			
			FROM termine
			LEFT JOIN seminare ON (termine.range_id = seminare.Seminar_id)
			LEFT JOIN seminar_user USING (Seminar_id)
			LEFT JOIN object_user_visits ON (termine.termin_id = object_user_visits.object_id AND object_user_visits.user_id = seminar_user.user_id)
			LEFT JOIN themen_termine USING (termin_id)
			LEFT JOIN themen USING (issue_id)
			WHERE seminar_user.user_id = '$user_id'
			AND (termine.chdate > '$since' OR themen.chdate > '$since')
			ORDER BY termine.chdate DESC
			";


		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			if ($data['termine_chdate'] > $data['themen_chdate'])
				$chdate = $data['termine_chdate'];
			else $chdate = $data['themen_chdate'];
			
			if ($data['object_id'] && $chdate > $data['visitdate'])
			{
				$read = '1';
			} else {
				$read = '0';
			}
			if ($data['title'])
			{
				$title = $data['title'];
			} else {
				$title = $data['Name'];
			}

			$ret[] = array(
				'object_id'   => $data['termin_id'],
				'object_type' => 'schedule',
				'title'       => $title,
				'description' => $data['Name'],
				'date'        => $chdate,
				'read'        => $read
			);
		}

		return (array) $ret;
	}

	static function getDocuments($seminar_id, $user_id)
	{

	}

	static function hasNewsAuthorization($user_id, $news_id) {

		$query = "SELECT count(*)
			FROM news
			LEFT JOIN news_range USING (news_id)
			LEFT JOIN seminare ON (news_range.range_id = seminare.Seminar_id)
			LEFT JOIN seminar_user USING (Seminar_id)
			WHERE news.news_id = '$news_id'
			AND seminar_user.user_id = '$user_id'
			";
				
		$db = DBManager::get()->query($query);
		$data = $db->fetch(PDO::FETCH_ASSOC);
		return $data['count(*)'] > 0;
		
	}
	
	/**
	 * Liefert einen bestimmten News-Artikel.
	 * @param id ID des Artikels
	 * @return Tabellenspalten:<p/>
	 * {@code topic} Überschrift<p/>
	 * {@code body} Nachrichten-Rumpf<p/>
	 * {@code auther} Verfasser<p/>
	 * {@code date} Datum der letzten Änderung<p/>
	 * {@code range} Bereich (Veranstaltung) auf den sich der Artikel bezieht
	 */
	static function getNews($news_id)
	{
		
		$query = "SELECT news.news_id, news.topic, news.body, news.author, news.date, seminare.Name
			FROM news
			LEFT JOIN news_range USING (news_id)
			LEFT JOIN seminare ON (news_range.range_id = seminare.Seminar_id)
			WHERE news.news_id = '$news_id'";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			if ($data['Name'])
			{
				$range= $data['Name'];
			} else {
				$range= 'Systemweite News';
			}
			$ret[] = array(
				'topic'		=> $data['topic'],
				'body'		=> $data['body'],
				'author'	=> $data['author'],
				'date'		=> $data['date'],
				'range'		=> $range
			);
		}

		return (array) $ret;
	}

	static function hasMessageAuthorization($user_id, $message_id) {

		$query = "SELECT count(*)
			FROM message_user
			WHERE user_id = '$user_id'
			AND message_id = '$message_id'
		";
		
		$db = DBManager::get()->query($query);
		$data = $db->fetch(PDO::FETCH_ASSOC);
		return $data['count(*)'] > 0;
		
	}
	
	/**
	 * Liefert eine bestimmte Nachricht.
	 * @param id ID der Nachricht
	 * @return Tabellenspalten:<p/>
	 * {@code subject} Betreff
	 * {@code date} Datum
	 * {@code author} Verfasser der Nachricht
	 * {@code text} Inhalt der Nachricht
	 * {@code author_uname} Username des Verfassers
	 */
	static function getMessage($message_id)
	{
		$query = "SELECT message.subject, Vorname, Nachname, message.mkdate, message.message, auth_user_md5.username
			FROM message
			LEFT JOIN auth_user_md5 ON (auth_user_md5.user_id = autor_id)
			LEFT JOIN message_user ON (message_user.message_id = message.message_id)
			WHERE message.message_id='$message_id'";

		$db = DBManager::get()->query($query);

		if ($data = $db->fetch(PDO::FETCH_ASSOC))
		{
			
			$ret[] = array(
				'subject'	=> $data['subject'],
				'date'		=> $data['mkdate'],
				'author'	=> $data['Vorname']." ".$data['Nachname'],
				'text'		=> $data['message'],
				'author_uname'	=> $data['username']
			);

		}

		return (array) $ret;
	}

	/**
	 * Versendet eine Nachricht.
	 * @param Spaltennamen:<p/>
	 * {@code recipient} Nutzername des Empfänger<p/>
	 * {@code subject} Betreff<p/>
	 * {@code text} Inhalt der Nachricht
	 * @return {@code true} bei erfolgreichem Versenden, {@code false} bei
	 * Misserfolg
	 */
	static function sendMessage($snd_id, $rec_uname, $subject, $text)
	{
		require_once('lib/messaging.inc.php');
		if (!get_userid($rec_uname)) return false;
		$m = new messaging();
		$rec_cnt = $m->insert_message($text, $rec_uname, $snd_id, null, null, null, null, $subject);
		if ($rec_cnt > 0) return true;
		else return false;
	}

	static function hasScheduleAuthorization($user_id, $schedule_id) {

		$query = "SELECT count(*)
			FROM termine
			LEFT JOIN themen_termine USING (termin_id)
			LEFT JOIN themen USING (issue_id)
			LEFT JOIN seminare ON (seminare.Seminar_id = termine.range_id)
			LEFT JOIN seminar_user ON (seminare.Seminar_id = seminar_user.Seminar_id)
			WHERE termin_id='$schedule_id'
			AND seminar_user.user_id = '$user_id'
			";
						
		$db = DBManager::get()->query($query);
		$data = $db->fetch(PDO::FETCH_ASSOC);
		return $data['count(*)'] > 0;
		
	}
	
	/**
	 * Liefert einen bestimmten Termin.
	 * @param id ID des Termins
	 * @return Tabellenspalten:<p/>
	 * {@code title} Titel des Termins<p/>
	 * {@code range} Bereich (Veranstaltung) zu dem der Termin gehört<p/>
	 * {@code start} Startzeit<p/>
	 * {@code end} Endzeit<p/>
	 * {@code description} Beschreibung
	 */
	static function getSchedule($schedule_id)
	{
		$query = "SELECT themen.title, seminare.Name, termine.date, termine.end_time, themen.description
			FROM termine
			LEFT JOIN themen_termine USING (termin_id)
			LEFT JOIN themen USING (issue_id)
			LEFT JOIN seminare ON (seminare.Seminar_id = termine.range_id)
			WHERE termin_id='$schedule_id'
			";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			if ($data['Name'])
			{
				$range= $data['Name'];
			} else {
				$range= 'Systemweite News';
			}
			$ret[] = array(
				'title'		=> $data['title'],
				'range'		=> $range,
				'start'		=> $data['date'],
				'end'		=> $data['end_time'],
				'description'	=> $data['description']
			);
		}

		return (array) $ret;
	}

	/**
	 * Markiert eine Resource als gelesen.
	 * @param type Resourcentyp
	 * @param id ID der Resource
	 */
	static function setObjectVisited($object_id, $type, $user_id)
	{
		switch ($type) {
		case 'message':
			$query = "UPDATE IGNORE message_user SET readed=1 WHERE user_id='$user_id' AND message_id='$object_id'";
			DBManager::get()->query($query);
			break;
		default:
			require_once('lib/object.inc.php');
			return object_set_visit($object_id, $type, $user_id);
		}
	}

	static function searchPerson($expression)
	{
		
	}
	
	static function getUserSeminars($user_id)
	{
		$query = "SELECT seminare.Name, seminare.Seminar_id
			FROM seminar_user
			LEFT JOIN seminare USING (Seminar_id)
			WHERE user_id='$user_id'
			";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'object_id'		=> $data['Seminar_id'],
				'title'		=> $data['Name']
			);
		}

		return (array) $ret;
	}
	
	static function getSeminarDetails($seminar_id)
	{
		$query = "SELECT seminare.Seminar_id, seminare.Name, seminare.Untertitel, seminare.Beschreibung, seminare.Ort
			FROM seminare
			WHERE Seminar_id='$seminar_id'
			";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'object_id'		=> $data['Seminar_id'],
				'title'			=> $data['Name'],
				'subtitle'		=> $data['Untertitel'],
				'description'	=> $data['Beschreibung'],
				'location'		=> $data['Ort']
			);
		}

		return (array) $ret;
	}

	static function hasSeminarAuthorization($user_id, $seminar_id) {

		$query = "SELECT count(*)
			FROM seminar_user
			WHERE Seminar_id = '$seminar_id'
			AND user_id = '$user_id'
			";
				
		$db = DBManager::get()->query($query);
		$data = $db->fetch(PDO::FETCH_ASSOC);
		return $data['count(*)'] > 0;
		
	}
	
	static function getSeminarParticipants($seminar_id)
	{
		$query = "SELECT auth_user_md5.username, auth_user_md5.Vorname, auth_user_md5.Nachname, seminar_user.status
			FROM seminar_user
			LEFT JOIN auth_user_md5 USING (user_id)
			WHERE seminar_user.Seminar_id='$seminar_id'
			AND seminar_user.visible='yes'
			";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'username'		=> $data['username'],
				'fullname'		=> $data['Vorname']." ".$data['Nachname'],
				'status'		=> $data['status']
			);
		}

		return (array) $ret;
	}

	static function getIncomingMessages($user_id, $since)
	{
		$query = "SELECT message.message_id, message.subject, Vorname, Nachname, message.mkdate, message_user.readed
			FROM message
		        LEFT JOIN message_user USING (message_id)
			LEFT JOIN auth_user_md5 ON (auth_user_md5.user_id = autor_id)
			WHERE message_user.user_id='$user_id'
			AND snd_rec='rec'
			AND message.mkdate > '$since'
			ORDER BY message.mkdate DESC";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'object_id'   => $data['message_id'],
				'object_type' => 'message',
				'title'       => $data['subject'],
				'description' => $data['Vorname']." ".$data['Nachname'],
				'date'        => $data['mkdate'],
				'read'        => $data['readed']
			);
		}

		return (array) $ret;

	}
	
	static function getOutgoingMessages($user_id, $since)
	{
		$query = "SELECT message.message_id, message.subject, Vorname, Nachname, message.mkdate, message_user.readed
			FROM message
		    LEFT JOIN message_user USING (message_id)
			LEFT JOIN auth_user_md5 ON (auth_user_md5.user_id = autor_id)
			WHERE message_user.user_id='$user_id'
			AND snd_rec='snd'
			AND message.mkdate > '$since'
			ORDER BY message.mkdate DESC";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'object_id'   => $data['message_id'],
				'object_type' => 'message',
				'title'       => $data['subject'],
				'description' => $data['Vorname']." ".$data['Nachname'],
				'date'        => $data['mkdate'],
				'read'        => $data['readed']
			);
		}

		return (array) $ret;

	}
	
	static function exportSchedule($user_id, $since)
	{
		$query = "SELECT 
			termine.termin_id, 
			themen.title, 
			termine.raum,
			seminare.Ort,
			seminare.Name, 
			termine.date, 
			termine.end_time, 
			termine.chdate AS termine_chdate,
			themen.chdate AS themen_chdate, 
			object_user_visits.object_id, 
			themen.description
			
			FROM termine
			LEFT JOIN seminare ON (termine.range_id = seminare.Seminar_id)
			LEFT JOIN seminar_user USING (Seminar_id)
			LEFT JOIN object_user_visits ON (termine.termin_id = object_user_visits.object_id AND object_user_visits.user_id = seminar_user.user_id)
			LEFT JOIN themen_termine USING (termin_id)
			LEFT JOIN themen USING (issue_id)
			WHERE seminar_user.user_id = '$user_id'
			AND (termine.chdate > $since OR themen.chdate > $since)
			ORDER BY termine.chdate DESC
			";

//			AND termine.end_time > '$now'
		
		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			
			$range= $data['Name'];
			if (!$range) $range= 'Systemweite News';
			
			$title = $data['title'];
			if (!$title) $title = $data['Name'];
			
			$location = $data['raum'];
			if (!$location) $location = $data['Ort'];
			
			$description = $data['description'];
			
			$chdate = $data['termine_chdate'];
			if ($chdate < $data['themen_chdate']) 
					$chdate = $data['themen_chdate'];
			
			$ret[] = array(
				'object_id'   	=> $data['termin_id'],
				'title'			=> $title,
				'location'		=> $location,
				'description'	=> $description,
				'start'			=> $data['date'],
				'end'			=> $data['end_time'],
				'chdate'		=> $chdate
			);
		}

		return (array) $ret;

	}
	
	static function getVisitedObjectsSince($user_id, $since) {
		
		$query = "SELECT object_id, visitdate
			FROM object_user_visits
			WHERE user_id='$user_id'
			AND visitdate > '$since'";

		$db = DBManager::get()->query($query);

		while ($data = $db->fetch(PDO::FETCH_ASSOC)) {
			$ret[] = array(
				'object_id'   	=> $data['object_id'],
				'visitdate'			=> $data['visitdate']
			);
		}

		return (array) $ret;

	}	
	
	// TODO woher genommen?
	static function checkCredentials($username, $password)
	{
		$GLOBALS['sess'] = new Seminar_Session(); // needed for StudipAuthStandard

		return StudipAuthAbstract::CheckAuthentication($username, $password);
	}
	
}
